//
//  THNetworkManager.swift
//  Practise
//
//  Created by flower on 2017/8/24.
//  Copyright © 2017年 lalala. All rights reserved.
//

import UIKit
import AFNetworking

/// Swift 的枚举支持任意数据类型
/// switdh / enum 在 OC 中都只是支持整数
enum THHTTPMEthod {
    case GET
    case POST
}
/// 网络管理工具
class THNetworkManager: AFHTTPSessionManager {

    // 静态区 / 常量 / 闭包
    // 在第一次访问的时候, 执行闭包, 并且将结果保存在 shared 常量中
   // static let shared = THNetworkManager()
    static let shared: THNetworkManager = {
    
        // 实例化对象
        let instance = THNetworkManager()
        // 设置响应反序列化支持的数据类型
        instance.responseSerializer.acceptableContentTypes?.insert("text/plain")
        // 返回对象
        return instance
    }()
    /// 访问令牌, 所有网络请求, 都基于此令牌(登录除外)
//    var accessToken: String? //= "2.00dPzaQDgnAdrDaa48e67db0VnE5fD"
//    var uid: String? = "5365823342"
    
    
    /// 用户账户懒加载属性
    lazy var userAccount = THUserAccount()
    
    /// 用户登录标记[计算型属性]  没有等号 末尾没有括号  相当于省略个get
    var  userLogon: Bool {
        return userAccount.access_token != nil
    }
    
    /// 专门负责拼接 token 的网络请求方法
    func tokenRequest(method: THHTTPMEthod = .GET, URLString: String, parameters: [String: Any]?, completion: @escaping (_ json: Any?, _ isSuccess: Bool) -> ()) {
        // 处理 token 字典
        // 0> 判断 token 是否为 nil, 为 nil 直接返回
        guard let token = userAccount.access_token else {
            print("没有 token ! 需要登录")
            // 发送通知, 提醒用户登录
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: THUserShouldLoginNotification),
                                            object: nil)
            
            completion(nil, false)
            return
        }
        // 1> 判断 参数字典是否存在, 如果为 nil 应该新创建一个字典
        var parameters = parameters
        if parameters == nil {
            //实例化字典
            parameters = [String: Any]()
        }
        // 2> 设置参数字典, 代码在此处字典一定有值
        parameters?["access_token"] = token
        // 调用 request 发起真正的网络请求方法
        request(method: method, URLString: URLString, parameters:parameters!, completion:completion)
    }
    
    /// 使用一个函数封装 AFN 的 GET / POST 请求
    ///
    /// - Parameters:
    ///   - method:     GET  /  POST
    ///   - URLString:   URLString
    ///   - parameters:  参数字典
    ///   - completion:  完成回调[json(字典 / 数组), 是否成功]
    func request(method: THHTTPMEthod = .GET, URLString: String, parameters: [String: Any], completion: @escaping (_ json: Any?, _ isSuccess: Bool) -> ()) {
        
        // 成功回调
        let success = { (task: URLSessionDataTask, json: Any?) -> () in
            
            completion(json, true)
        }
        
        // 失败回调
        let failure = { (task: URLSessionDataTask?, error: Error) -> () in
            // 针对 403 处理用户过期
            // 对于测试用户(应用程序还没有提交给新郎微博审核) 每天的刷新了量是有限的
            // 超出上限, token 会锁定一段时间 
            // 解决办法, 新建一个应用程序!
            if (task?.response as? HTTPURLResponse)?.statusCode == 403{
                print("token 过期了")
                
                // 发送通知, 提醒用户再次登录(本方法不知道被谁调用, 谁接收到方法, 谁处理!)
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: THUserShouldLoginNotification), object: "bad token")
            }
            
            // error 通常比较吓人, 例如  编号: XXXXX 错误原因一堆英文
            print("网络请求错误 \(error)")
            
            completion(nil, false)
        }
    
        if method == .GET {
            
            get(URLString, parameters: parameters, progress: nil, success: success, failure: failure)

        } else {
        
            post(URLString, parameters: parameters, progress: nil, success: success, failure: failure)
        }
    }
    
}
